Program testing and error elimination is an important part in the development process of virtually any computer program. A program developer usually runs the program on a computer and analyzes the computer's output to verify whether the program behaves as expected and to identify possible errors (bugs). The programmer may then modify the program in order to remove such bugs. This is known as debugging.
Various debugging tools are known in the art. A debugging tool or debugger is a hardware or software device which is designed to assist the programmer in finding bugs in a computer program. For example, a debugger may enable the programmer to monitor the values of variables during a run of the computer program. Furthermore, a debugger may indicate the instruction in the source code of the program at which an exception has occurred during a run of the program. An exception may indicate, represent, or can be any kind of error that is not expected to happen during normal execution of the program. Exceptions may include, for example, forbidden mathematical operations such as division by 0, memory errors such as heap or stack overflow errors, and segmentation faults.
Many of the most common methods of debugging a program involve analyzing a trace that is generated by the computer when running the program. A trace may be defined as any collection of data that is accumulated during the execution of a program. A trace may, for example, include the values of a variable at different stages of the program flow. Alternatively or in addition, the trace may indicate the names of instructions that are executed during the program flow. Such instructions may be indicated in the trace to various degrees of precision. For example, if the program has been written in a modular manner involving modules such as function or subroutines, the program may be designed, for example, to write out only the names of higher level modules but not the names of the lower level modules contained in or called by the high level modules. For instance, a program may be configured such that the name of a subroutine A is appended to the trace when the subroutine is called by a processor, whereas the name of a subroutine B included in subroutine A is not appended to the trace when subroutine B is executed as part of subroutine A. Alternatively, a computer may be configured such that the names of modules belonging to various modular levels are accounted for in the trace. By analyzing the trace, the programmer may reconstruct the program flow that occurred when the program was executed on a computer.